/*
** Copyright (C) 2009 Joshua Brent Marsh <joshua@icub3d.com>
**  
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**  
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**  
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**  
*/

/* $Id: test_function_prototypes.c 32 2009-10-28 22:51:19Z joshua@icub3d.com $ */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>

#include <CUnit/Basic.h>

#include "../src/function_prototypes.h"

#include "test_function_prototypes.h"

int
init_test_function_prototype_suite ()
{
  return 0;
}

int
clean_test_function_prototype_suite ()
{
  return 0;
}

void
test_function_prototype_comp_int ()
{
  int x = 5, y = 10, *z;
  
  z = malloc (sizeof (int));
  if (z == NULL)
    CU_FAIL ("malloc z failed.");

  *z = 15;


  CU_ASSERT (comp_int (&x, &x) == 0);  
  CU_ASSERT (comp_int (&x, &y) < 0);
  CU_ASSERT (comp_int (&x, z) < 0);

  CU_ASSERT (comp_int (&y, &x) > 0);  
  CU_ASSERT (comp_int (&y, &y) == 0);
  CU_ASSERT (comp_int (&y, z) < 0);

  CU_ASSERT (comp_int (z, &x) > 0);  
  CU_ASSERT (comp_int (z, &y) > 0);
  CU_ASSERT (comp_int (z, z) == 0);


  dest_int (z);
}

void
test_function_prototype_comp_char ()
{
  char x = 'A', y = 'B', *z;
  
  z = malloc (sizeof (char));
  if (z == NULL)
    CU_FAIL ("malloc z failed.");

  *z = 'C';


  CU_ASSERT (comp_char (&x, &x) == 0);  
  CU_ASSERT (comp_char (&x, &y) < 0);
  CU_ASSERT (comp_char (&x, z) < 0);

  CU_ASSERT (comp_char (&y, &x) > 0);  
  CU_ASSERT (comp_char (&y, &y) == 0);
  CU_ASSERT (comp_char (&y, z) < 0);

  CU_ASSERT (comp_char (z, &x) > 0);  
  CU_ASSERT (comp_char (z, &y) > 0);
  CU_ASSERT (comp_char (z, z) == 0);


  dest_char (z);
}

void
test_function_prototype_comp_double ()
{
  double x = 5.59683, y = 5.79382, *z;
  
  z = malloc (sizeof (double));
  if (z == NULL)
    CU_FAIL ("malloc z failed.");

  *z = 5.79383;


  CU_ASSERT (comp_double (&x, &x) == 0);  
  CU_ASSERT (comp_double (&x, &y) < 0);
  CU_ASSERT (comp_double (&x, z) < 0);

  CU_ASSERT (comp_double (&y, &x) > 0);  
  CU_ASSERT (comp_double (&y, &y) == 0);
  CU_ASSERT (comp_double (&y, z) < 0);

  CU_ASSERT (comp_double (z, &x) > 0);  
  CU_ASSERT (comp_double (z, &y) > 0);
  CU_ASSERT (comp_double (z, z) == 0);


  dest_double (z);
}

void
test_function_prototype_comp_float ()
{
  float x = 5.59683, y = 5.79382, *z;
  
  z = malloc (sizeof (float));
  if (z == NULL)
    CU_FAIL ("malloc z failed.");

  *z = 5.79383;


  CU_ASSERT (comp_float (&x, &x) == 0);  
  CU_ASSERT (comp_float (&x, &y) < 0);
  CU_ASSERT (comp_float (&x, z) < 0);

  CU_ASSERT (comp_float (&y, &x) > 0);  
  CU_ASSERT (comp_float (&y, &y) == 0);
  CU_ASSERT (comp_float (&y, z) < 0);

  CU_ASSERT (comp_float (z, &x) > 0);  
  CU_ASSERT (comp_float (z, &y) > 0);
  CU_ASSERT (comp_float (z, z) == 0);


  dest_float (z);
}

void
test_function_prototype_comp_string ()
{
  char *x = "test1", *y = "test1 too", *z;
  
  z = malloc (strlen ("test1 too too") + 1);
  if (z == NULL)
    CU_FAIL ("malloc z failed.");

  strcpy (z, "test1 too too");

  CU_ASSERT (comp_string (x, x) == 0);  
  CU_ASSERT (comp_string (x, y) < 0);
  CU_ASSERT (comp_string (x, z) < 0);

  CU_ASSERT (comp_string (y, x) > 0);  
  CU_ASSERT (comp_string (y, y) == 0);
  CU_ASSERT (comp_string (y, z) < 0);

  CU_ASSERT (comp_string (z, x) > 0);  
  CU_ASSERT (comp_string (z, y) > 0);
  CU_ASSERT (comp_string (z, z) == 0);


  dest_string (z);
}

void
test_function_prototype_comp_ispair ()
{
  ISPair *x, *y, *z;

  x = create_ispair (1, "value 1");
  if (x == NULL)
    {
      CU_FAIL ("creating x failed.");

      return;
    }

  y = create_ispair (2, "value 2");
  if (y == NULL)
    {
      dest_ispair (x);
      CU_FAIL ("creating y failed.");

      return;
    }

  z = create_ispair (3, "value 3");
  if (z == NULL)
    {
      dest_ispair (x);
      dest_ispair (y);
      CU_FAIL ("creating z failed.");

      return;
    }

  CU_ASSERT_EQUAL (x->id, 1);
  CU_ASSERT_STRING_EQUAL (x->value, "value 1");

  CU_ASSERT_EQUAL (y->id, 2);
  CU_ASSERT_STRING_EQUAL (y->value, "value 2");

  CU_ASSERT_EQUAL (z->id, 3);
  CU_ASSERT_STRING_EQUAL (z->value, "value 3");


  CU_ASSERT (comp_ispair (x, x) == 0);  
  CU_ASSERT (comp_ispair (x, y) < 0);
  CU_ASSERT (comp_ispair (x, z) < 0);

  CU_ASSERT (comp_ispair (y, x) > 0);  
  CU_ASSERT (comp_ispair (y, y) == 0);
  CU_ASSERT (comp_ispair (y, z) < 0);

  CU_ASSERT (comp_ispair (z, x) > 0);  
  CU_ASSERT (comp_ispair (z, y) > 0);
  CU_ASSERT (comp_ispair (z, z) == 0);


  dest_ispair (x);
  dest_ispair (y);
  dest_ispair (z);
}

void
test_function_prototype_comp_sspair ()
{
  SSPair *x, *y, *z;

  x = create_sspair ("first", "value 1");
  if (x == NULL)
    {
      CU_FAIL ("creating x failed.");

      return;
    }

  y = create_sspair ("second", "value 2");
  if (y == NULL)
    {
      dest_sspair (x);
      CU_FAIL ("creating y failed.");

      return;
    }

  z = create_sspair ("third", "value 3");
  if (z == NULL)
    {
      dest_sspair (x);
      dest_sspair (y);
      CU_FAIL ("creating z failed.");

      return;
    }

  CU_ASSERT_STRING_EQUAL (x->name, "first");
  CU_ASSERT_STRING_EQUAL (x->value, "value 1");

  CU_ASSERT_STRING_EQUAL (y->name, "second");
  CU_ASSERT_STRING_EQUAL (y->value, "value 2");

  CU_ASSERT_STRING_EQUAL (z->name, "third");
  CU_ASSERT_STRING_EQUAL (z->value, "value 3");

  CU_ASSERT (comp_sspair (x, x) == 0);  
  CU_ASSERT (comp_sspair (x, y) < 0);
  CU_ASSERT (comp_sspair (x, z) < 0);

  CU_ASSERT (comp_sspair (y, x) > 0);  
  CU_ASSERT (comp_sspair (y, y) == 0);
  CU_ASSERT (comp_sspair (y, z) < 0);

  CU_ASSERT (comp_sspair (z, x) > 0);  
  CU_ASSERT (comp_sspair (z, y) > 0);
  CU_ASSERT (comp_sspair (z, z) == 0);


  dest_sspair (x);
  dest_sspair (y);
  dest_sspair (z);
}

int
make_function_prototype_suite (CU_pSuite s)
{
  s = CU_add_suite ("Test Function Prototype Suite", 
		    init_test_function_prototype_suite, 
		    clean_test_function_prototype_suite);
  if (s == NULL)
    {
      return CU_get_error();
    }

  if (CU_add_test (s, "test comp_int", 
		   test_function_prototype_comp_int) == NULL ||
      CU_add_test (s, "test comp_char", 
		   test_function_prototype_comp_char) == NULL ||
      CU_add_test (s, "test comp_double", 
		   test_function_prototype_comp_double) == NULL ||
      CU_add_test (s, "test comp_float", 
		   test_function_prototype_comp_float) == NULL ||
      CU_add_test (s, "test comp_string", 
		   test_function_prototype_comp_string) == NULL ||
      CU_add_test (s, "test comp_ispair", 
		   test_function_prototype_comp_ispair) == NULL ||
      CU_add_test (s, "test comp_sspair", 
		   test_function_prototype_comp_sspair) == NULL)
    {
      return CU_get_error();
    }

  return CU_get_error();
}

